package com.yang.test.service.serviceImpl;


import com.yang.test.mapper.MbtiMapper;
import com.yang.test.domain.Dimension;
import com.yang.test.domain.Question;
import com.yang.test.domain.Result;
import com.yang.test.domain.VO.QuestionVO;
import com.yang.test.domain.VO.ResultVO;
import com.yang.test.service.DeepseekService;
import com.yang.test.service.MbtiService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.*;

@Slf4j
@Service
public class MbtiServiceImpl implements MbtiService {
    
    @Autowired
    private MbtiMapper mbtiMapper;
    
    @Autowired
    private DeepseekService deepseekService;
    
    @Override
    public List<QuestionVO> getQuestions(String testType) {
        List<String> types;
        switch (testType) {
            case "simple":
                types = Collections.singletonList("simple");
                break;
            case "detailed":
                types = Arrays.asList("simple", "detailed");
                break;
            case "full":
                types = Arrays.asList("simple", "detailed", "full");
                break;
            default:
                log.warn("无效的测试类型: {}, 使用simple类型", testType);
                types = Collections.singletonList("simple");
        }
        
        List<Question> questions = mbtiMapper.getQuestionsByTypes(types);
        List<QuestionVO> questionVOs = new ArrayList<>();
        
        for (Question q : questions) {
            QuestionVO vo = new QuestionVO();
            vo.setId(q.getId());
            vo.setQuestion(q.getQuestion());
            vo.setDimension(q.getDimension());
            vo.setDirection(q.getDirection());
            // 设置7级量表选项
            vo.setOptions(Arrays.asList("非常不符合", "不符合", "有点不符合", "中立", "有点符合", "符合", "非常符合"));
            questionVOs.add(vo);
        }
        
        return questionVOs;
    }
    
    @Override
    public String processAnswers(List<Integer> answers, String testType) {
        // 计算MBTI维度得分
        Map<String, Double> scores = calculateScores(answers, testType);
        
        // 生成结果ID
        String resultId = generateResultId();
        
        // 根据得分确定MBTI类型
        String mbtiType = determineMbtiType(scores);
        log.info("计算得到MBTI类型: {}, 得分: {}", mbtiType, scores);
        
        // 生成维度数据
        List<Dimension> dimensions = Arrays.asList(
            new Dimension("E", "I", Math.round(100 - scores.getOrDefault("EI", 0.0)), Math.round(scores.getOrDefault("EI", 0.0))),
            new Dimension("S", "N", Math.round(100 - scores.getOrDefault("SN", 0.0)), Math.round(scores.getOrDefault("SN", 0.0))),
            new Dimension("T", "F", Math.round(100 - scores.getOrDefault("TF", 0.0)), Math.round(scores.getOrDefault("TF", 0.0))),
            new Dimension("J", "P", Math.round(100 - scores.getOrDefault("JP", 0.0)), Math.round(scores.getOrDefault("JP", 0.0)))
        );
        
        // 生成个性化报告
        String report = deepseekService.generateReport(mbtiType, dimensions);
        
        // 创建结果对象
        Result result = new Result();
        result.setId(resultId);
        result.setType(mbtiType);
        result.setDimensions(dimensions);
        result.setReport(report);
        result.setCreatedAt(new Date());
        
        // 保存结果到数据库
        int rows = mbtiMapper.saveResult(result);
        log.info("结果保存完成, 影响行数: {}", rows);
        
        return resultId;
    }
    
    @Override
    public ResultVO getResult(String resultId) {
        Result result = mbtiMapper.getResultById(resultId);
        
        if (result == null) {
            return null;
        }
        
        // 转换为视图对象
        ResultVO resultVO = new ResultVO();
        resultVO.setId(result.getId());
        resultVO.setType(result.getType());
        resultVO.setDimensions(result.getDimensions());
        resultVO.setReport(result.getReport());
        
        return resultVO;
    }
    
    @Override
    public Map<String, Double> calculateScores(List<Integer> answers, String testType) {
        Map<String, Double> scores = new HashMap<>();
        
        // 根据测试类型确定题目范围
        List<String> types;
        switch (testType) {
            case "simple":
                types = Collections.singletonList("simple");
                break;
            case "detailed":
                types = Arrays.asList("simple", "detailed");
                break;
            case "full":
                types = Arrays.asList("simple", "detailed", "full");
                break;
            default:
                log.warn("无效的测试类型: {}", testType);
                return scores;
        }
        
        // 查询题目信息
        List<Map<String, Object>> questions = mbtiMapper.getQuestionDimensionsAndDirections(types);
        
        // 计算每个维度的得分
        Map<String, ScoreInfo> dimensionScores = new HashMap<>();
        
        for (int i = 0; i < Math.min(answers.size(), questions.size()); i++) {
            Map<String, Object> question = questions.get(i);
            String dimension = (String) question.get("dimension");
            int direction = ((Number) question.get("direction")).intValue();
            
            // 确保答案在1-7的范围内
            int answer = answers.get(i);
            if (answer < 1) answer = 1;
            if (answer > 7) answer = 7;
            
            // 计算得分（考虑题目方向）
            double score;
            if (direction == 1) {
                score = (answer - 1) * (100.0 / 6.0); // 正向题目：将1-7线性映射到0-100
            } else {
                score = (7 - answer) * (100.0 / 6.0); // 反向题目：将7-1线性映射到0-100
            }
            
            // 确保得分在0-100范围内
            if (score < 0) score = 0;
            if (score > 100) score = 100;
            
            // 累加分数
            ScoreInfo scoreInfo = dimensionScores.getOrDefault(dimension, new ScoreInfo());
            scoreInfo.setTotal(scoreInfo.getTotal() + score);
            scoreInfo.setCount(scoreInfo.getCount() + 1);
            dimensionScores.put(dimension, scoreInfo);
        }
        
        // 计算每个维度的最终得分
        for (Map.Entry<String, ScoreInfo> entry : dimensionScores.entrySet()) {
            String dim = entry.getKey();
            ScoreInfo info = entry.getValue();
            
            if (info.getCount() > 0) {
                // 计算平均分并确保在0-100范围内
                double avgScore = info.getTotal() / info.getCount();
                if (avgScore < 0) avgScore = 0;
                if (avgScore > 100) avgScore = 100;
                scores.put(dim, (double) Math.round(avgScore));
            }
        }
        
        return scores;
    }
    
    @Override
    public String determineMbtiType(Map<String, Double> scores) {
        StringBuilder mbtiType = new StringBuilder();
        
        // 当分数等于50时，默认选择第二个类型
        if (scores.getOrDefault("EI", 0.0) >= 50) {
            mbtiType.append("E");
        } else {
            mbtiType.append("I");
        }
        
        if (scores.getOrDefault("SN", 0.0) >= 50) {
            mbtiType.append("S");
        } else {
            mbtiType.append("N");
        }
        
        if (scores.getOrDefault("TF", 0.0) >= 50) {
            mbtiType.append("T");
        } else {
            mbtiType.append("F");
        }
        
        if (scores.getOrDefault("JP", 0.0) >= 50) {
            mbtiType.append("J");
        } else {
            mbtiType.append("P");
        }
        
        return mbtiType.toString();
    }
    
    private String generateResultId() {
        return "result_" + Instant.now().toEpochMilli();
    }
    
    // 内部类用于存储每个维度的分数信息
    @Data
    private static class ScoreInfo {
        private double total = 0;
        private int count = 0;
    }
}